package vip.finance.makemoney.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import feign.Response;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import vip.finance.makemoney.apiSpider.eastmoney.EastMoneyTradeApi;
import vip.finance.makemoney.apiSpider.eastmoney.ReqAuthentication;
import vip.finance.makemoney.common.RestEnum;
import vip.finance.makemoney.common.vo.UserInfo;
import vip.finance.makemoney.config.UserContextManager;
import vip.finance.makemoney.config.exception.BusinessException;
import vip.finance.makemoney.entity.User;
import vip.finance.makemoney.entity.UserTrade;
import vip.finance.makemoney.mapper.UserMapper;
import vip.finance.makemoney.service.IUserService;
import vip.finance.makemoney.service.IUserTradeService;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yangbin
 * @since 2023-01-19
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Resource
    UserContextManager userContextManager;
    @Resource
    EastMoneyTradeApi eastmoneyTradeApi;
    @Resource
    IUserTradeService userTradeService;

    /**
     * 登录
     */
    @Override
    public UserInfo login(String account, String password) {
        User user = getOne(Wrappers.<User>lambdaQuery().eq(User::getUsername, account));
        if (user == null) {
            throw new BusinessException(RestEnum.USER_ACCOUNT_NOT_EXIST);
        }
        if (!Objects.equals(user.getPassword(), SecureUtil.md5(password))) {
            throw new BusinessException(RestEnum.USER_PASSWORD_ERROR);
        }
        return userContextManager.saveUserContext(user);
    }

    /**
     * 证券登录
     */
    @Override
    public void loginTrade(UserInfo currentUser, String randNum, String identifyCode, String password) {
        List<UserTrade> list = userTradeService.list(Wrappers.<UserTrade>lambdaQuery().eq(UserTrade::getUserId, currentUser.getId()));
        currentUser.setCookieList(new ArrayList<>());
        for (UserTrade tradeUser : list) {
            ReqAuthentication req = new ReqAuthentication();
            req.setUserId(tradeUser.getAccountId());
            req.setPassword(encodePassword(password));
            req.setRandNumber(randNum);
            req.setIdentifyCode(identifyCode);
            //获取cookie
            Response response = eastmoneyTradeApi.authentication(req);
            response.body();
            String cookie = response.headers().get("set-cookie").stream().map(this::getCookieStr).collect(Collectors.joining());
            UserInfo.EastMoneyCookie eastMoneyCookie = new UserInfo.EastMoneyCookie();
            currentUser.getCookieList().add(eastMoneyCookie);
            eastMoneyCookie.setUserTradeId(tradeUser.getId());
            eastMoneyCookie.setAccountId(tradeUser.getAccountId());
            eastMoneyCookie.setCookie(cookie);
            //获取validateKey
            String validateKey = getValidateKey(eastmoneyTradeApi.tradeBuy());
            eastMoneyCookie.setValidatekey(validateKey);
            userContextManager.saveUserContext(currentUser);
            log.info("currentUser:{}", currentUser);
        }
    }

    private String getCookieStr(String content) {
        String key = "expires=";
        int inputBegin = content.indexOf(key);
        return content.substring(0, inputBegin);
    }

    private String getValidateKey(String content) {
        String key = "input id=\"em_validatekey\" type=\"hidden\" value=\"";
        int inputBegin = content.indexOf(key) + key.length();
        int inputEnd = content.indexOf("\" />", inputBegin);
        return content.substring(inputBegin, inputEnd);
    }

    private String encodePassword(String password) {
        if (password.length() != 6) {
            return password;
        }
        String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHdsyxT66pDG4p73yope7jxA92\nc0AT4qIJ/xtbBcHkFPK77upnsfDTJiVEuQDH+MiMeb+XhCLNKZGp0yaUU6GlxZdp\n+nLW8b7Kmijr3iepaDhcbVTsYBWchaWUXauj9Lrhz58/6AE/NF0aMolxIGpsi+ST\n2hSHPu3GSXMdhPCkWQIDAQAB";
        return SecureUtil.rsa(null, publicKey).encryptBase64(password.getBytes(StandardCharsets.UTF_8), KeyType.PublicKey);
    }
}
